package com.panopset.game.blackjack;

import java.io.StringWriter;

import com.panopset.game.DollarConverter;


/**
 * Bankroll.
 *
 * @author Karl Dinwiddie
 *
 */
public class Bankroll {

    @Override
    public String toString() {
        StringWriter sw = new StringWriter();
        sw.append("Total Chips: ");
        sw.append("" + getTotalChips());
        sw.append(" Tray : ");
        sw.append("" + getChipsInTray());
        sw.append(" cashBalance: ");
        sw.append("" + getCashBalance());
        sw.append(" total: " + getTotalStakeCashBalancePlusChips());
        return sw.toString();
    }

    private final ReloadSupplier rs;
    private long reloads = 0;

    public long getReloadCount() {
        return reloads;
    }

    public Bankroll(ReloadSupplier reloadSupplier) {
        rs = reloadSupplier;
    }

    /**
     * Reset ledger to 0.
     */
    public synchronized void reset() {
        chips = 0;
        balance = 0L;
    }

    /**
     * Reload amount.
     */
    private Integer reloadAmount;

    /**
     * Balance.
     */
    private Long balance;

    /**
     * @return Balance.
     */
    public synchronized long getBalance() {
        check();
        return balance + getChips();
    }

    /**
     * Chips.
     */
    private Integer chips;

    /**
     * @return Chips.
     */
    public synchronized int getChips() {
        check();
        return chips;
    }

    /**
     * Make sure there is a positive amount of chips.
     */
    private synchronized void check() {
        if (balance == null) {
            balance = 0L;
        }
        if (chips == null) {
            chips = 0;
        }
        if (chips < 1) {
            reloads++;
            int rldAmt = new DollarConverter().str2long(rs
                    .getRawReloadAmountFromConfig()).intValue();
            if (rldAmt < 1) {
                rldAmt = ConfigDft.DEFAULT_INITIAL_STAKE;
            }
            chips += rldAmt;
            balance -= rldAmt;
        }
    }

    public synchronized void init() {
        check();
        getBalance();
    }

    /**
     * @param amount Amount to add to chip stack.
     */
    public synchronized void removeChips(final int amount) {
        init();
        chips -= amount;
        check();
    }

    /**
     * @param amount Amount to add to chip stack.
     */
    public synchronized void addChips(final int amount) {
        init();
        chips += amount;
    }

    public static interface ReloadSupplier {
        public String getRawReloadAmountFromConfig();
    }

    public long getTotalChips() {
        return getChips();
    }

    public long getTotalStakeCashBalancePlusChips() {
        return getBalance();
    }

    public void addChipsInTray(int i) {
        addChips(i);
    }

    public void bet(int i) {
        addChips(-i);
    }

    public long getCashBalance() {
        return getBalance();
    }

    public Integer getChipsInTray() {
        return getChips();
    }
}
